#pragma once

#include "ace\Asynch_IO.h"
#include "ace\inet_addr.h"

#include "assert.h"

#include <vector>

class __declspec (dllexport) CNetworkPlugin
{
public:
	CNetworkPlugin(unsigned short type);
	virtual ~CNetworkPlugin(void) = 0;
public:
	virtual int OnOpen() = 0;

	virtual int OnRecv(const char * in, size_t inlen, char * out, size_t & outlen) = 0;

	virtual int OnSend(const char * in, size_t inlen, char * out, size_t & outlen) = 0;

	virtual int OnClose() = 0;

	unsigned short Type() const
	{
		return m_Type;
	}
private:
	unsigned short m_Type;
};

class CPluginBase
{
public:
	CPluginBase() { };
	virtual ~CPluginBase()
	{
		for(unsigned int i = 0; i < m_Plugin.size(); i++)
		{
			if(m_Plugin[i])
			{
				m_Plugin[i]->OnClose();
				delete m_Plugin[i];
				m_Plugin[i] = 0;
			}
		}
	};
public:
	void AttachPlugin(CNetworkPlugin * plugin)
	{
		if(plugin)
		{
			for(unsigned int i = 0; i < m_Plugin.size(); i++)
			{
				if(m_Plugin[i]->Type() == plugin->Type())
				{
					m_Plugin[i]->OnClose();
					delete m_Plugin[i];
					m_Plugin[i] = plugin;
					plugin->OnOpen();

					return ;
				}
			}

			m_Plugin.push_back(plugin);

			plugin->OnOpen();
		}
	}

	void DeattachPlugin(CNetworkPlugin * plugin)
	{
		if(plugin)
		{
			for(unsigned int i = 0; i < m_Plugin.size(); i++)
			{
				if(m_Plugin[i] == plugin)
				{
					plugin->OnClose();
					m_Plugin[i] = 0;
					delete plugin;
				}
			}
		}
	}
protected:
	std::vector<CNetworkPlugin *> m_Plugin;
};